package com.example.paopao.consumer.job.handler;

import com.example.paopao.common.enumerator.ServiceCode;
import com.example.paopao.common.exception.ServiceException;
import com.example.paopao.common.web.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.nio.file.AccessDeniedException;
import java.util.Set;


@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*全局异常处理器*/
    @ExceptionHandler
    public JsonResult handleServiceException(ServiceException e){
        return JsonResult.fail(e);
    }

    @ExceptionHandler
    public JsonResult handleBindExceptin(BindException e){
        String message=e.getFieldError().getDefaultMessage();
        return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST,message);
    }

    @ExceptionHandler
    public JsonResult handleConstrainViolationException(ConstraintViolationException e){
        /*
        * ConstraintViolationException是一个java中的异常类，通常与数据访问和持久化框架一起使用
        * 当使用这些框架进行数据操作时，如果违反了定义的约束条件，就会排除ContrainViolationException
        * 这种异常表示在执行数据库操作期间发生了约束违规的情况
        * */
        String message=null;
        Set<ConstraintViolation<?>> constraintViolations=e.getConstraintViolations();
        /*
        * ConstraintViolation 是一个常见的概念，指在应用程序中违反了预定约束条件的情况
        * 我们经常使用约束来限制数据的有效性和一致性，在数据中，可以定义表和列级别的约束
        * 例如：唯一约束，非空约束，外键约束
        * */
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            message=constraintViolation.getMessage();/*getMessage() 本质是this.interpolatedMessage;*/
        }
        /*ERROR_BAD_REQUEST:请求参数错误*/
        return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST,message);
    }

    @ExceptionHandler
    public JsonResult handleAccessDeniedException(AccessDeniedException e){
        String message="操作失败，您当前登录的账号无此操作权限！";
        /*ERROR_FORBIDDEN:禁止访问，用于无权限*/
        return JsonResult.fail(ServiceCode.ERROR_FORBIDDEN,message);
    }

    @ExceptionHandler
    public JsonResult handleThrowable(Throwable e){
        log.warn("程序运行过程中出现未知异常：",e);
        String message="操作失败，服务器忙，请稍后再试！";
        /*ERROR_UNKNOWN:其他异常*/
        return JsonResult.fail(ServiceCode.ERROR_UNKNOWN,message);
    }
}
